package com.amitk.foldersizecalc.utils.impl;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import com.amitk.foldersizecalc.utils.FileAndFolderCalc;

public class FileAndFolderCalcImpl implements FileAndFolderCalc {

	public List<Entry> getFileAndFolderList(String path) {
		List<Entry> list = new ArrayList<FileAndFolderCalc.Entry>();
		File file = new File(path);
		if (file.isDirectory()) {
			EntryImpl entryImpl = new EntryImpl("", 0.0, Boolean.TRUE);
			File[] filelist = file.listFiles();
			double totalSize = 0;
			if(filelist == null)
				return new ArrayList<FileAndFolderCalc.Entry>();
			for (File filee : filelist) {
				List<Entry> fileAndFolderList = getFileAndFolderList(filee
						.getAbsolutePath());

				for (Entry entry : fileAndFolderList) {
					totalSize += entry.getSizeInMB();
				}
				
				entryImpl.setEntryLocation(file.getAbsolutePath());
				entryImpl.setSizeInMB(getTwoDecimalValue(totalSize));

				for (Entry entry : fileAndFolderList) {
					if (entry.isDirectory())
						entryImpl.childList.add(entry);
				}

			}
			list.add(entryImpl);
		} else {
			long bytes = file.length();
			double sizeInMB =  (bytes / (1024.0 * 1024.0));
			sizeInMB = getTwoDecimalValue(sizeInMB);
			list.add(new EntryImpl(file.getAbsolutePath(), sizeInMB,
					Boolean.FALSE));
		}
		return list;
	}

	private double getTwoDecimalValue(double sizeInMB) {
		BigDecimal bd = new BigDecimal(sizeInMB);
		bd = bd.setScale(2, RoundingMode.HALF_UP);
		return bd.doubleValue();
	}

	class EntryImpl implements Entry{

		private String entryLocation;
		private double sizeInMB;
		private boolean directory;
		private List<Entry> childList;

		public EntryImpl(String entryLocation, double sizeInMB,
				boolean directory) {
			childList = new ArrayList<FileAndFolderCalc.Entry>();
			this.entryLocation = entryLocation;
			this.sizeInMB = sizeInMB;
			this.directory = directory;
		}

		public List<Entry> getChilds() {
			return childList;
		}

		public String getEntryLocation() {
			return this.entryLocation;
		}

		public double getSizeInMB() {
			return this.sizeInMB;
		}

		public boolean isDirectory() {
			return this.directory;
		}

		public void setEntryLocation(String entryLocation) {
			this.entryLocation = entryLocation;
		}

		public void setSizeInMB(double sizeInMB) {
			this.sizeInMB = sizeInMB;
		}

		public void setDirectory(boolean directory) {
			this.directory = directory;
		}

		public int compareTo(Entry o) {
			try{
			return (int) (o.getSizeInMB() - sizeInMB);
			}catch(Throwable e){
				e.printStackTrace();
				return 0;
			}
		}

	}

}
